package stockin

import (
	"context"
	"fmt"
	"golang.org/x/sync/errgroup"
	"net/http"
	"strings"
	"sync"
	"wms/model"

	"wms/internal/svc"
	"wms/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type StockinListLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewStockinListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *StockinListLogic {
	return &StockinListLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *StockinListLogic) StockinList(req *types.StockInListRequest) (resp *types.StockInListResponse, err error) {
	resp = new(types.StockInListResponse)
	//1.分页
	var query string
	var querys []string
	if req.StartTime > 0 {
		querys = append(querys, fmt.Sprintf("date>='%d'", req.StartTime))
	}
	if req.EndTime > 0 {
		querys = append(querys, fmt.Sprintf("date<=%d", req.EndTime))
	}

	if len(querys) > 0 {
		query = " where " + strings.Join(querys, " and ")
	}

	queryWithLimit := query + fmt.Sprintf(" order by status asc, date desc limit %d,%d", (req.Page-1)*req.Size, req.Size)
	stockins, err := l.svcCtx.StockInModel.FindByPage(l.ctx, queryWithLimit)
	switch err {
	case nil:
	case model.ErrNotFound:
		resp.Code = http.StatusOK
		resp.Msg = "成功"
		return resp, nil
	default:
		fmt.Printf("[Error]入库单分页:%s\n", err.Error())
		resp.Code = http.StatusInternalServerError
		resp.Msg = "服务内部错误"
		return resp, nil
	}

	total, err := l.svcCtx.StockInModel.Count(l.ctx, query)
	if err != nil {
		fmt.Printf("[Error]查询入库单总数:%s\n", err.Error())
		resp.Code = http.StatusInternalServerError
		resp.Msg = "服务内部错误"
		return resp, nil
	}

	//2.入库单详情
	var mux sync.RWMutex
	var g errgroup.Group
	var stockinDetails = make(map[int64][]model.StockInDetail) //key:入库单id
	for _, stockin := range stockins {
		one := stockin
		g.Go(func() error {
			var e error
			var details []model.StockInDetail
			details, e = l.svcCtx.StockInDetailModel.FindByPage(l.ctx, fmt.Sprintf(" where stock_id=%d", one.Id))
			if e != nil {
				fmt.Printf("[Error]入库单[%d]详情:%s\n", one.Id, e.Error())
				return e
			}
			mux.Lock()
			stockinDetails[one.Id] = details
			mux.Unlock()

			return nil
		})
	}

	if err = g.Wait(); err != nil {
		fmt.Printf("[Error]查询入库单列表详情:%s\n", err.Error())
		resp.Code = http.StatusInternalServerError
		resp.Msg = "服务内部错误"
		return resp, nil
	}

	//3.数据汇总
	resp.Data.Total = total
	for _, stockin := range stockins {
		var one = types.StockIn{
			Id:            stockin.Id,
			SupplierId:    stockin.SupplierId,
			SupplierName:  stockin.SupplierName,
			Status:        stockin.Status,
			BalanceStatus: stockin.BalanceStatus,
			HasTax:        stockin.HasTax,
			Tax:           stockin.Tax,
			Total:         stockin.Total,
			Deposit:       stockin.Deposit,
			Date:          stockin.Date,
		}

		for _, detail := range stockinDetails[one.Id] {
			one.List = append(one.List, types.StockInDetail{
				Id:            detail.Id,
				MaterialsId:   detail.MaterialsId,
				MaterialName:  detail.MaterialsName,
				MaterialTypes: detail.MaterialsTypes,
				Weight:        detail.Weight,
				Price:         detail.Price,
			})
		}
		resp.Data.List = append(resp.Data.List, one)
	}

	resp.Code = http.StatusOK
	resp.Msg = "成功"
	return resp, nil
}
